
package ch.fhnw.qualiscan.application.views;

import ch.fhnw.qualiscan.Config;
import ch.fhnw.qualiscan.application.components.InformationBox;
import ch.fhnw.qualiscan.application.controllers.NewSurvey;
import ch.fhnw.qualiscan.application.elements.WeighDomain;
import ch.fhnw.qualiscan.core.View;
import ch.fhnw.qualiscan.core.db.fieldfactories.SurveyFieldFactory;
import ch.fhnw.qualiscan.core.db.helpers.addUserToSurveyArgs;
import ch.fhnw.qualiscan.core.db.helpers.questionWeightArgs;
import ch.fhnw.qualiscan.core.db.pojos.Domain;
import ch.fhnw.qualiscan.core.db.pojos.Question;
import ch.fhnw.qualiscan.core.db.pojos.Questionnaire;
import ch.fhnw.qualiscan.core.db.pojos.Stage;
import ch.fhnw.qualiscan.core.db.pojos.Survey;
import ch.fhnw.qualiscan.core.db.pojos.SurveyUserRole;
import ch.fhnw.qualiscan.core.db.pojos.User;
import com.vaadin.data.Property;
import com.vaadin.data.Validator;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.terminal.UserError;
import com.vaadin.ui.Accordion;
import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Panel;
import com.vaadin.ui.RichTextArea;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import eu.livotov.tpt.i18n.TM;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author bengro
 */
public class NewSurveyView extends View {
    
    NewSurvey controller;
    
    //Layout Components
    public Label title;
    public TabSheet.Tab tab1;
    public TabSheet.Tab tab2;
    public TabSheet.Tab tab3;
    public TabSheet.Tab tab4;
    public Form generalInfoForm;
    public Form addParticipantsForm;
    public Accordion questionWeightingAccordion;
    public TextField[] participantsRole;
    
    //Tabs
    public VerticalLayout TabComponent1;
    public VerticalLayout TabComponent2;
    public VerticalLayout TabComponent3;
    public VerticalLayout TabComponent4;
    
    // UI elements tab 4
    public List<SurveyUserRole> surList;
    public RichTextArea emailEditor;
    public Button saveButton;
    public VerticalLayout formArea;

    Panel p1;
    Panel p2;
	
    
    public NewSurveyView(NewSurvey newSurveyController) {
        this.controller = newSurveyController;
    }
    
    @Override
    public void initComponents() {

    }

    @Override
    public void buildLayout() {
        
        TabComponent1 = tabComponent1();
        TabComponent2 = tabComponent2();
        TabComponent3 = tabComponent3();
        TabComponent4 = tabComponent4();

        title = textHelper.h1(TM.get("newsurvey.title"));
        addComponent(title);

        tabSheet.setHeight("");
        tabSheet.setWidth("100%");

        tab1 = tabSheet.addTab(TabComponent1, TM.get("newsurvey.tab1.title"), null);
        tab2 = tabSheet.addTab(TabComponent2, TM.get("newsurvey.tab2.title"), null);
        tab3 = tabSheet.addTab(TabComponent3, TM.get("newsurvey.tab3.title"), null);
        tab4 = tabSheet.addTab(TabComponent4, TM.get("newsurvey.tab4.title"), null);

        tab2.setEnabled(false);
        tab3.setEnabled(false);
        tab4.setEnabled(false);
            
        VerticalLayout formWrapper = new VerticalLayout();
    	formWrapper.setMargin(true);
            
        addComponent(tabSheet);
        
    }
    
    private VerticalLayout tabComponent1() {
        
        TabComponent1 = new VerticalLayout();
        TabComponent1.setMargin(true);
        
        // title
        TabComponent1.addComponent(textHelper.h3(TM.get("newsurvey.tab1.general.title")));

        // helper box
        //TabComponent1.addComponent(new InformationBox());

        // show questionnaire select
        TabComponent1.addComponent(showSelect());
        
        // if selected show form
        formArea = new VerticalLayout();
        TabComponent1.addComponent(formArea);
        
        return TabComponent1;
        
    }
    
    public VerticalLayout showSelect() {
        VerticalLayout selectWrap = new VerticalLayout();
        
        // get all questionnaires
        List<Questionnaire> questionnaires = controller.questionnaireModel.getActiveQuestionnaires(controller.userSessionHelper.getUser());

        final BeanItemContainer<Questionnaire> constellationContainer = new BeanItemContainer<Questionnaire> (Questionnaire.class);
        constellationContainer.addAll(questionnaires);

        final NativeSelect l = new NativeSelect(TM.get("admin.selectquestionnaire"), constellationContainer);

        l.setNullSelectionAllowed(false);
        l.setItemCaptionPropertyId("title");
        l.setImmediate(true);
        l.setRequired(true);
        l.setRequiredError(TM.get("survey.error.questionnaire"));
        l.addListener(new Property.ValueChangeListener() {
            public void valueChange(Property.ValueChangeEvent event) {
                controller.selectedQuestionnaire = (Questionnaire) event.getProperty().getValue();
                formArea.removeAllComponents();
                formArea.addComponent(showForm());
            }
        });

        
        selectWrap.setMargin(true, false, true, false);
        selectWrap.addComponent(l);
        
        return selectWrap;
    }
    
    /**
     * Takes care of the first tab, where survey title, domains and completion date are selected.
     * @return 
     */
    private VerticalLayout showForm() {
        VerticalLayout tabComponent = new VerticalLayout();
        
        generalInfoForm = new Form();
        generalInfoForm.setDescription(TM.get("newsurvey.tab1.general.desc"));
        
        controller.survey.setCreationdate(new java.util.Date());
        Stage firstStage = new Stage();
        firstStage.setId(1);
        controller.survey.setStage(firstStage);
        
        BeanItem<Survey> item = new BeanItem<Survey>(controller.survey);
        
        generalInfoForm.setItemDataSource(item);
        generalInfoForm.setImmediate(true);
        generalInfoForm.setFormFieldFactory(new SurveyFieldFactory(controller.selectedQuestionnaire));
        
        Vector<String> order = new Vector<String>();
        order.add("title");
        order.add("domains");
        order.add("completiondate");
        order.add("category");
        order.add("university");
        
        generalInfoForm.setVisibleItemProperties(order);
        HorizontalLayout buttonBar = new HorizontalLayout();
        generalInfoForm.getFooter().addComponent(buttonBar);
       
        //next step button
        Button commit;
        commit = new Button(TM.get("action.next"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                try {
                    generalInfoForm.commit();
                    Set s = controller.survey.getDomains();
                    System.out.println(s.size());
                    controller.survey.setDomains(new HashSet());
                    Iterator i = s.iterator();
                    while (i.hasNext()) {
                            Domain d = new Domain();
                            d.setId((Integer)i.next());
                            controller.survey.addDomain(d);
                    }
                    tab2.setEnabled(true);
                    buildWeighing();

                    tabSheet.setSelectedTab(TabComponent2);
                    tab1.setEnabled(false);
                }
                catch (Validator.InvalidValueException e) {
                    return;
                }
            }
        });
        commit.setIcon(Config.ICON_GO_TAB);
        buttonBar.addComponent(commit);
        
        tabComponent.addComponent(generalInfoForm);
        return tabComponent;
    }
    
    /**
     * Create placeholder for content - Weighing domains.
     * @return 
     */
    private VerticalLayout tabComponent2() {
        VerticalLayout tabComponent = new VerticalLayout();
        tabComponent.setMargin(true);
        
        return tabComponent;
    }
    
    /**
     * Builds the actual weighing tab
     */
    private void buildWeighing() {
        
        controller.selectedDomains = new ArrayList<Domain>();
        List<Domain> domainList = new ArrayList<Domain>();
        Iterator<Domain> domainIterator = controller.survey.getDomains().iterator();

        while(domainIterator.hasNext()) {
            domainList.add(domainIterator.next());
        }

        int size = domainList.size();
        for (int a = 0; a < size; a++) {
            Domain nextDomain = domainList.get(0);

            for(int o = 0; o < domainList.size(); o++) {
                if(nextDomain.getId() > domainList.get(o).getId()) {
                        nextDomain = domainList.get(o);
                }
            }

            controller.selectedDomains.add(nextDomain);
            domainList.remove(nextDomain);
        }

        TabComponent2.addComponent(textHelper.p(TM.get("newsurvey.tab2.desc")));
        TabComponent2.addComponent(addWeighHeader());

        controller.weighList = new ArrayList<WeighDomain>();

        for(int i = 0; i < controller.selectedDomains.size(); i++) {
            addDomainItem(controller.selectedDomains.get(i));
        }

        // next step button
        HorizontalLayout buttonWrap = new HorizontalLayout();
        buttonWrap.setMargin(true, false, false, false);

        Button saveButton = new Button(TM.get("action.next"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                controller.questionWeights = new ArrayList<questionWeightArgs>();

                for(int o = 0; o < controller.weighList.size(); o++) {
                    WeighDomain weighDomain = controller.weighList.get(o);
                    int weigh = weighDomain.getWeight();
                    Domain persistentDomain = controller.domainModel.getDomainById(weighDomain.domain.getId());
                    Iterator<Question> questionIterator = persistentDomain.getQuestions().iterator();

                    while(questionIterator.hasNext()) {

                        questionWeightArgs qwa = new questionWeightArgs();
                        qwa.setQuestion(questionIterator.next());
                        qwa.setWeight(weigh);

                        controller.questionWeights.add(qwa);
                    }
                }

                tab3.setEnabled(true);
                tabSheet.setSelectedTab(TabComponent3);
                tab2.setEnabled(false);
            }
        });
        saveButton.setIcon(Config.ICON_GO_TAB);
        buttonWrap.addComponent(saveButton);

        TabComponent2.addComponent(buttonWrap);
    }

    public void addDomainItem(Domain d) {
        // load WeighDomain item
        WeighDomain weighDomain = new WeighDomain(d);

        //Save to List
        controller.weighList.add(weighDomain);

        // add component to layout
        TabComponent2.addComponent(weighDomain);
    }

    public HorizontalLayout addWeighHeader() {
        // header
        HorizontalLayout header = new HorizontalLayout();
        header.setWidth("800px");
        header.setMargin(true, false, true, false);

        HorizontalLayout headerForm = new HorizontalLayout();

        // first column (agree)
        Label c1 = new Label(TM.get("weight.1"));
        c1.setStyleName("weight1");
        c1.setHeight("100%");

        // second column 
        Label c2 = new Label(TM.get("weight.2"));
        c2.setStyleName("weight2");
        c2.setHeight("100%");

        // second column 
        Label c3 = new Label(TM.get("weight.3"));
        c3.setStyleName("weight3");
        c3.setHeight("100%");

        headerForm.addComponent(c1);
        headerForm.addComponent(c2);
        headerForm.addComponent(c3);

        headerForm.setWidth("270px");
        headerForm.setHeight("35px");
        headerForm.setStyleName("formColumns");

        Label headerSpacer = new Label("");
        header.addComponent(headerSpacer);
        header.addComponent(headerForm);
        header.setExpandRatio(headerSpacer, 1.0f);

        return header;
    }
    
    /**
     * Participants page: can be loaded in advance, does not depend on state.
     * @return 
     */
    private VerticalLayout tabComponent3() {
        addParticipantsForm = new Form();
        
        //newSurvey.addParticipantsForm.setCaption(TM.get("newsurvey.tab3.general.title"));
        addParticipantsForm.setDescription(TM.get("newsurvey.tab3.general.desc"));
        controller.roleList = controller.roleModel.getParticipantRoles();
        participantsRole = new TextField[controller.roleList.size()];
        
    	for(int i = 0; i < controller.roleList.size(); i++) {
            participantsRole[i] = new TextField();
            participantsRole[i].setInputPrompt("test@test.com\ntest@test.com\ntest@test.com\ntest@test.com");
            participantsRole[i].setRows(8);
            participantsRole[i].setColumns(25);
            participantsRole[i].setCaption(controller.userModel.getRoleText(controller.roleList.get(i), controller.userSession.getLanguage()).getTitle());
            addParticipantsForm.addField(controller.roleList.get(i).getId(), participantsRole[i]);
    	}
    	
    	final HorizontalLayout buttonBar = new HorizontalLayout();
    	addParticipantsForm.getFooter().addComponent(buttonBar);
    	
    	// next button
        Button commit = new Button(TM.get("action.next"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                controller.participantsRoleList = new ArrayList<addUserToSurveyArgs>();
                addParticipantsForm.commit();
                
                int error = 0;
                Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
                for(int i = 0; i < controller.roleList.size(); i++) {
                    String participants = (String) participantsRole[i].getValue();
                    if (participants != null) {
                        String[] participantsSplited = participants.split("\\n");
                        for(int u = 0; u < participantsSplited.length; u++) {
                            if (participantsSplited[u] != "") {
                                Matcher m = p.matcher(participantsSplited[u]);
                                if (m.matches()) {
                                    User user = controller.userModel.addUser(participantsSplited[u]);
                                    addUserToSurveyArgs aua = new addUserToSurveyArgs(user, controller.roleList.get(i));
                                    controller.participantsRoleList.add(aua);
                                }
                                else {
                                    error = 1;
                                }
                            }
                        }
                    }	
                }

                if(error == 0) {
                    tab4.setEnabled(true);
                    tabSheet.setSelectedTab(TabComponent4);
                    tab3.setEnabled(false);
                }
                else {
                    //At least one email address is invalid
                    addParticipantsForm.setComponentError(new UserError(TM.get("newsurvey.tab3.form.invalidemail")));
                    Button commitWithoutCor = new Button(TM.get("action.nextwithoutchange"), new Button.ClickListener() {
                        public void buttonClick(Button.ClickEvent event) {
                            tab4.setEnabled(true);
                            tabSheet.setSelectedTab(TabComponent4);
                            tab3.setEnabled(false);
                        }
                    });
                    buttonBar.addComponent(commitWithoutCor);
                }
            }
        });
        commit.setIcon(Config.ICON_GO_TAB);
        
        buttonBar.addComponent(commit);
		
        VerticalLayout tabComponent = new VerticalLayout();
        tabComponent.setMargin(true);
        tabComponent.addComponent(addParticipantsForm);
        
        return tabComponent;
    }
    
    /**
     * Completion and storing
     * @return 
     */
    private VerticalLayout tabComponent4() {
        TabComponent4 = new VerticalLayout();
        TabComponent4.setMargin(true);
        
        p1 = new Panel();
		
        p1.addComponent(textHelper.h2(TM.get("newsurvey.tab4.p1.title")));
        p1.addComponent(textHelper.p(TM.get("newsurvey.tab4.p1.desc")));

        // save button
        saveButton = new Button(TM.get("newsurvey.tab4.save"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                p1.setEnabled(false);
                saveButton.setEnabled(false);
                controller.saveToDatabase();
            }
        });
        saveButton.setIcon(Config.ICON_SAVE);
        
        VerticalLayout buttonWrap = new VerticalLayout();
        buttonWrap.setMargin(true, false, false, false);
        buttonWrap.addComponent(saveButton);
        
        p1.addComponent(buttonWrap);

        TabComponent4.addComponent(p1);
        
        return TabComponent4;
    }
    
    public void tabComponent4Invitations() {
        p2 = new Panel();
		
        saveButton.setCaption(TM.get("newsurvey.tab4.saved"));

        emailEditor = new RichTextArea();
        emailEditor.setWidth("100%");

        String coordinator = controller.userSession.getFirstname()+" "+ controller.userSession.getLastname(); 

        Label text = new Label(TM.get("email.invitationtext", coordinator, controller.survey.getTitle()));
        text.setContentMode(Label.CONTENT_XHTML);

        emailEditor.setValue(text.getValue());

        p2.addComponent(textHelper.h2(TM.get("newsurvey.tab4.p2.title")));
        p2.addComponent(textHelper.p(TM.get("newsurvey.tab4.p2.desc")));

        p2.addComponent(emailEditor);

        // send email button
        Button sendInvitations = new Button(TM.get("newsurvey.tab4.p2.sendInvitation"), new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                controller.sendInvitations();
            }
        });
        sendInvitations.setIcon(Config.ICON_SENDMAIL);
        p2.addComponent(sendInvitations);

        /* send no email button
        Button noEmail = new Button(TM.get("newsurvey.tab4.p2.noemail"));
        noEmail.addListener(new Button.ClickListener() {
                public void buttonClick(ClickEvent event) {
                        newSurvey.urlLib.setPage("Dashboard");
                }
        });
        noEmail.setIcon(Config.ICON_SENDMAILNOT);
        */

        // buttons panel
        HorizontalLayout buttons = new HorizontalLayout();
        buttons.setSpacing(true);
        buttons.setMargin(true, false, false, false);
        buttons.addComponent(sendInvitations);
        //buttons.addComponent(noEmail);

        p2.addComponent(buttons);

        TabComponent4.addComponent(p2);
    }

    public void updateTab4() {
        p2.setEnabled(false);
    }

	@Override
	public void reBuild() {
		// TODO Auto-generated method stub
		
	}
    
}
